package com.market.service.admin.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.market.bean.MarketPermission;
import com.market.bean.MarketPermissionExample;
import com.market.bean.MarketRole;
import com.market.bean.MarketRoleExample;
import com.market.bean.bo.admin.AdminRoleCreateBo;

import com.market.bean.*;
import com.market.bean.bo.AdminPermissionBo;

import com.market.bean.bo.ChildByChildren;
import com.market.bean.bo.Children;

import com.market.bean.common.BasePageInfo;
import com.market.bean.common.CommonData;
import com.market.bean.vo.admin.AdminOptionsVo;
import com.market.bean.vo.admin.AdminPermissionVo;
import com.market.bean.vo.admin.AdminRoleCreateVo;
import com.market.bean.vo.admin.AdminSystemPermissionVo;
import com.market.mapper.MarketPermissionMapper;
import com.market.mapper.MarketSystemPermissionMapper;
import com.market.service.admin.AdminRoleService;
import com.market.mapper.MarketRoleMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 2731235517@qq.com 谢畅
 * @since 2022/12/29 23:06
 */

@Transactional
@Service
public class AdminRoleServiceImpl implements AdminRoleService {
    @Autowired
    MarketRoleMapper marketRoleMapper;
    @Autowired
    MarketPermissionMapper marketPermissionMapper;
    @Autowired
    MarketSystemPermissionMapper marketSystemPermissionMapper;

    @Override
    public CommonData<AdminOptionsVo> options() {
        MarketRoleExample marketRoleExample = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = marketRoleExample.createCriteria();

        criteria.andDeletedEqualTo(false);
        List<MarketRole> marketLogList = marketRoleMapper.selectByExample(marketRoleExample);
        List<AdminOptionsVo> adminOptionsVoList = marketLogList.stream()
                .map(result -> new AdminOptionsVo(result.getId(), result.getName()))
                .collect(Collectors.toList());

        PageHelper.startPage(1, adminOptionsVoList.size());
        PageInfo<AdminOptionsVo> pageInfo = new PageInfo<>(adminOptionsVoList);
        return CommonData.data(pageInfo);
    }

    @Override
    public CommonData<MarketRole> list(BasePageInfo basePageInfo, String name) {
        PageHelper.startPage(basePageInfo.getPage(), basePageInfo.getLimit());

        MarketRoleExample marketRoleExample = new MarketRoleExample();
        MarketRoleExample.Criteria criteria = marketRoleExample.createCriteria();
        // 如果不为空，则拼接条件
        if (!StringUtils.isEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        criteria.andDeletedEqualTo(false);
        // 根据sort做order排序
        marketRoleExample.setOrderByClause(basePageInfo.getSort() + " " + basePageInfo.getOrder());

        List<MarketRole> marketStorageList = marketRoleMapper.selectByExample(marketRoleExample);
        PageInfo<MarketRole> pageInfo = new PageInfo<>(marketStorageList);
        return CommonData.data(pageInfo);
    }

    @Override
    public AdminRoleCreateVo create(AdminRoleCreateBo adminRoleCreateBo) {
        MarketRole marketRole = new MarketRole();
        marketRole.setName(adminRoleCreateBo.getName());
        marketRole.setDesc(adminRoleCreateBo.getDesc());
        marketRole.setEnabled(true);
        marketRole.setAddTime(new Date());
        marketRole.setUpdateTime(new Date());
        marketRole.setDeleted(false);
        marketRoleMapper.insert(marketRole);

        MarketRole selectByPrimaryKey = marketRoleMapper.selectByPrimaryKey(marketRole.getId());
        AdminRoleCreateVo adminRoleCreateVo = new AdminRoleCreateVo();
        adminRoleCreateVo.setId(selectByPrimaryKey.getId());
        adminRoleCreateVo.setName(selectByPrimaryKey.getName());
        adminRoleCreateVo.setDesc(selectByPrimaryKey.getDesc());
        adminRoleCreateVo.setAddTime(selectByPrimaryKey.getAddTime());
        adminRoleCreateVo.setUpdateTime(selectByPrimaryKey.getUpdateTime());
        return adminRoleCreateVo;
    }

    @Override
    public void update(MarketRole marketRole) {
        MarketRole selectByPrimaryKey = marketRoleMapper.selectByPrimaryKey(marketRole.getId());
        selectByPrimaryKey.setName(marketRole.getName());
        selectByPrimaryKey.setDesc(marketRole.getDesc());
        selectByPrimaryKey.setUpdateTime(new Date());
        marketRoleMapper.updateByPrimaryKey(selectByPrimaryKey);
    }

    @Override
    public void delete(MarketRole marketRole) {
        MarketRole selectByPrimaryKey = marketRoleMapper.selectByPrimaryKey(marketRole.getId());
        selectByPrimaryKey.setUpdateTime(new Date());
        selectByPrimaryKey.setDeleted(true);
        marketRoleMapper.updateByPrimaryKey(selectByPrimaryKey);
    }

    @Override
    public AdminPermissionVo listPermissions(Integer roleId) {
        AdminPermissionVo adminPermissionVo = new AdminPermissionVo();
        MarketPermissionExample marketPermissionExample = new MarketPermissionExample();
        MarketPermissionExample.Criteria criteria = marketPermissionExample.createCriteria();
        if (roleId != null) {
            criteria.andRoleIdEqualTo(roleId);
        }
        criteria.andDeletedEqualTo(false);

        List<MarketPermission> marketPermissionList = marketPermissionMapper.selectByExample(marketPermissionExample);
        List<String> assignedPermissions = marketPermissionList.stream()
                .map(result -> result.getPermission())
                .collect(Collectors.toList());

        List<AdminPermissionVo.SystemPermissionsEntity> systemPermissions = new LinkedList<>();
        List<String> models = marketRoleMapper.selectModels();
        for (String model : models) {
            AdminPermissionVo.SystemPermissionsEntity systemPermissionsEntity = new AdminPermissionVo().new SystemPermissionsEntity();
            systemPermissionsEntity.setId(model);
            systemPermissionsEntity.setLabel(model);

            List<AdminPermissionVo.SystemPermissionsEntity.ChildrenEntity> childrenEntities = new LinkedList<>();
            List<String> functions = marketRoleMapper.selectFunctionsByModel(model);
            for (String function : functions) {
                AdminPermissionVo.SystemPermissionsEntity.ChildrenEntity childrenEntity =
                        new AdminPermissionVo().new SystemPermissionsEntity().new ChildrenEntity();

                childrenEntity.setId(function);
                childrenEntity.setLabel(function);

                List<AdminPermissionVo.SystemPermissionsEntity.ChildrenEntity.ChildrenEntityEntity> childrenEntityEntities = new LinkedList<>();
                List<AdminSystemPermissionVo> permissions = marketRoleMapper.selectPermissionsByFunction(function);
                for (AdminSystemPermissionVo permissionVo : permissions) {
                    AdminPermissionVo.SystemPermissionsEntity.ChildrenEntity.ChildrenEntityEntity childrenEntityEntity =
                            new AdminPermissionVo().new SystemPermissionsEntity().new ChildrenEntity().new ChildrenEntityEntity();

                    childrenEntityEntity.setId(permissionVo.getId());
                    childrenEntityEntity.setLabel(permissionVo.getLabel());
                    childrenEntityEntity.setApi(permissionVo.getApi());
                    childrenEntityEntities.add(childrenEntityEntity);
                }

                childrenEntity.setChildren(childrenEntityEntities);
                childrenEntities.add(childrenEntity);
            }
            systemPermissionsEntity.setChildren(childrenEntities);
            systemPermissions.add(systemPermissionsEntity);
        }
        if (roleId == 1) {
            adminPermissionVo.setAssignedPermissions(marketRoleMapper.selectPermissions());
        } else {
            adminPermissionVo.setAssignedPermissions(assignedPermissions);
        }
        adminPermissionVo.setSystemPermissions(systemPermissions);
        return adminPermissionVo;
    }

    @Override
    public void updatePermissions(List<String> permissions, Integer roleId) {
        // 先把所有权限清空（逻辑删除）
        deleteAll(roleId);
        /*if (permissions.size() == 0) {
            return;
        }*/
        for (String permission : permissions) {
            int count = marketPermissionMapper.selectCountByPermission(permission, roleId);
            // 不存在则插入
            if (count == 0) {
                insert(permission, roleId);
            } else {
                // 存在则更新（授权）
                MarketPermissionExample marketPermissionExampleFalse = new MarketPermissionExample();
                MarketPermissionExample.Criteria criteriaFalse = marketPermissionExampleFalse.createCriteria();
                if (roleId != null) {
                    criteriaFalse.andRoleIdEqualTo(roleId);
                }
                if (!StringUtils.isEmpty(permission)) {
                    criteriaFalse.andPermissionEqualTo(permission);
                }
                List<MarketPermission> marketPermissionList = marketPermissionMapper.selectByExample(marketPermissionExampleFalse);
                MarketPermission marketPermission = marketPermissionList.get(0);
                marketPermission.setUpdateTime(new Date());
                marketPermission.setDeleted(false);
                marketPermissionMapper.updateByExample(marketPermission, marketPermissionExampleFalse);
                marketPermissionExampleFalse.clear();
            }
        }
    }

    private void deleteAll(Integer roleId) {
        MarketPermissionExample marketPermissionExample = new MarketPermissionExample();
        MarketPermissionExample.Criteria criteria = marketPermissionExample.createCriteria();
        if (roleId != null) {
            criteria.andRoleIdEqualTo(roleId);
        }
        List<MarketPermission> marketPermissionList = marketPermissionMapper.selectByExample(marketPermissionExample);

        for (MarketPermission permission : marketPermissionList) {
            MarketPermissionExample marketPermissionExampleTrue = new MarketPermissionExample();
            MarketPermissionExample.Criteria criteriaTrue = marketPermissionExampleTrue.createCriteria();
            if (roleId != null) {
                criteriaTrue.andRoleIdEqualTo(roleId);
            }
            if (!StringUtils.isEmpty(permission.getPermission())) {
                criteriaTrue.andPermissionEqualTo(permission.getPermission());
            }
            permission.setDeleted(true);
            marketPermissionMapper.updateByExample(permission, marketPermissionExampleTrue);
        }
    }

    private void insert(String permission, Integer roleId) {
        MarketPermission marketPermission = new MarketPermission();
        marketPermission.setRoleId(roleId);
        marketPermission.setPermission(permission);
        marketPermission.setAddTime(new Date());
        marketPermission.setUpdateTime(new Date());
        marketPermission.setDeleted(false);
        marketPermissionMapper.insert(marketPermission);
    }

    @Override
    public void insertSystemPermissions(List<AdminPermissionBo> adminPermissionBoList) {
        for (AdminPermissionBo adminPermissionBo : adminPermissionBoList) {
            MarketSystemPermission marketSystemPermission = new MarketSystemPermission();
            marketSystemPermission.setModel(adminPermissionBo.getLabel());

            List<Children> childrenList = adminPermissionBo.getChildren();
            for (Children children : childrenList) {
                marketSystemPermission.setFunction(children.getLabel());

                List<ChildByChildren> childByChildrenList
                        = children.getChildren();
                for (ChildByChildren childByChildren : childByChildrenList) {
                    marketSystemPermission.setApi(childByChildren.getApi());
                    marketSystemPermission.setPermission(childByChildren.getId());
                    marketSystemPermission.setLabel(childByChildren.getLabel());
                    marketSystemPermissionMapper.insert(marketSystemPermission);
                }
            }
        }
    }
}
